/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: cpu stat driver
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2023-09-20     JasonHu           Init
 */

#include <base/driver.h>

#define CONFIG_NX_DRIVER_CPUSTAT

#ifdef CONFIG_NX_DRIVER_CPUSTAT

#define NX_LOG_NAME "cpu stat driver"
#include <base/log.h>
#include <base/memory.h>
#include <base/smp.h>
#include <base/uaccess.h>
#include <base/perf.h>
#include <base/string.h>

#define DRV_NAME "cpu stat driver"
#define DEV_NAME "cpustat"

NX_PRIVATE NX_Error CpuStatRead(struct NX_Device *device, void *buf, NX_Offset off, NX_Size len, NX_Size *outLen)
{
    NX_CpuUsageInfo *cpuinfo;

    if (len != sizeof(NX_CpuUsageInfo))
    {
        return NX_EINVAL;
    }

    cpuinfo = (NX_CpuUsageInfo *)device->extension;

    NX_CopyToUser(buf, (char *)cpuinfo, len);

    if (outLen)
    {
        *outLen = len;
    }
    return NX_EOK;
}

NX_PRIVATE NX_DriverOps CpuStatDriverOps = {
    .read = CpuStatRead,
};

NX_PRIVATE void CpuStatDriverInit(void)
{
    NX_Device *device;
    int i;

    NX_Driver *driver = NX_DriverCreate(DRV_NAME, NX_DEVICE_TYPE_VIRT, 0, &CpuStatDriverOps);
    if (driver == NX_NULL)
    {
        NX_LOG_E("create driver failed!");
        return;
    }

    /* init all cpus */
    for (i = 0; i < NX_MULTI_CORES_NR; i++)
    {
        char name[16] = {0};
        NX_SNPrintf(name, 16, "%s%d", DEV_NAME, i);
        if (NX_DriverAttachDevice(driver, name, &device) != NX_EOK)
        {
            NX_LOG_E("attach device %s failed!", name);
            continue;
        }

        device->extension = &CpuUsageInfo[i];
    }

    if (NX_DriverRegister(driver) != NX_EOK)
    {
        NX_LOG_E("register driver %s failed!", DRV_NAME);
        NX_DriverCleanupDeviceOnly(driver);
        NX_DriverDestroy(driver);
        return;
    }
    
    NX_LOG_I("init %s driver success!", DRV_NAME);
}

NX_PRIVATE void CpuStatDriverExit(void)
{
    NX_DriverCleanup(DRV_NAME);
}

NX_DRV_INIT(CpuStatDriverInit);
NX_DRV_EXIT(CpuStatDriverExit);

#endif
